package com.huiminpay.agent.service;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePayModel;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeWapPayResponse;
import com.huiminpay.agent.api.PayChannelAgentService;
import com.huiminpay.agent.common.constant.AliCodeConstants;
import com.huiminpay.agent.conf.AliConfigParam;
import com.huiminpay.agent.dto.AlipayBean;
import com.huiminpay.agent.dto.PaymentResponseDTO;
import com.huiminpay.agent.dto.TradeStatus;
import com.huiminpay.agent.message.PayProducer;
import com.huiminpay.common.cache.domain.BusinessException;
import com.huiminpay.common.cache.domain.CommonErrorCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;

import javax.annotation.Resource;

@Slf4j
@Service
public class PayChannelAgentServiceImpl implements PayChannelAgentService {

    @Resource
    PayProducer payProducer;

    /**
     * \* 调用支付宝手机WAP下单接口
     * \* @param aliConfigParam 支付渠道参数
     * \* @param alipayBean 请求支付参数
     * \* @return
     * \* @throws BusinessException
     * @param aliConfigParam
     * @param alipayBean
     */
    @Override
    public PaymentResponseDTO createPayOrderByAliWAP(AliConfigParam aliConfigParam, AlipayBean alipayBean) throws BusinessException {
        log.info("支付宝请求参数", alipayBean.toString());

        // 支付宝sdk客户端
        DefaultAlipayClient client = new DefaultAlipayClient(aliConfigParam.getUrl(),aliConfigParam.getAppId(),aliConfigParam.getRsaPrivateKey(),aliConfigParam.getFormat(),aliConfigParam.getCharest(),aliConfigParam.getAlipayPublicKey(),aliConfigParam.getSigntype());
        // 封装请求支付信息
        AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();
        AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
        model.setOutTradeNo(alipayBean.getOutTradeNo());// 惠民平台订单
        model.setSubject(alipayBean.getSubject());// 订单标题
        model.setTotalAmount(alipayBean.getTotalAmount());// 订单金额
        model.setBody(alipayBean.getBody());// 订单内容
        model.setTimeoutExpress(alipayBean.getExpireTime());// 订单过期时间
        model.setProductCode(alipayBean.getProductCode());// 商户与支付宝签定的产品码，固定为QUICK_WAP_WAY
        alipayRequest.setBizModel(model);// 请求参数集合
        String jsonString = JSON.toJSONString(alipayBean);
        log.info("createPayOrderByAliWAP..alipayRequest:{}", jsonString);
        // 设置异步通知
        // 设置异步通知地址
        alipayRequest.setNotifyUrl(aliConfigParam.notifyUrl);
        // 设置同步地址
        alipayRequest.setReturnUrl(aliConfigParam.returnUrl);
        try {
            // 发送支付结果查询延迟消息
            PaymentResponseDTO<AliConfigParam> notice = new PaymentResponseDTO<AliConfigParam>();
            notice.setOutTradeNo(alipayBean.getOutTradeNo());
            notice.setContent(aliConfigParam);
            notice.setMsg("ALIPAY_WAP");
            payProducer.payOrderNotice(notice);
            // 调用SDK提交表单
            AlipayTradeWapPayResponse response = client.pageExecute(alipayRequest);
            log.info("支付宝手机网站支付预支付订单信息" + response);
            PaymentResponseDTO res = new PaymentResponseDTO();
            res.setContent(response.getBody());
            return res;
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException(CommonErrorCode.E_400002);// 支付宝确认支付失败
        }


    }

    /**
     * 支付宝交易状态查询
     * @param aliConfigParam 支付渠道参数
     * @param outTradeNo     惠民平台订单号
     * @return
     */
    @Override
    public PaymentResponseDTO queryPayOrderByAli(AliConfigParam aliConfigParam, String outTradeNo) {
        String gateway = aliConfigParam.getUrl();// 支付接口网关地址
        String appId = aliConfigParam.getAppId();// appid
        String rsaPrivateKey = aliConfigParam.getRsaPrivateKey(); // 私钥
        String format = aliConfigParam.getFormat();// json格式
        String charset = aliConfigParam.getCharest();// 编码 utf‐8
        String alipayPublicKey = aliConfigParam.getAlipayPublicKey(); // 公钥
        String signType = aliConfigParam.getSigntype();// 签名算法类型
        log.info("C扫B请求支付宝查询订单，参数：{}", JSON.toJSONString(aliConfigParam));

        // 构建sdk客户端
        AlipayClient client = new DefaultAlipayClient(gateway, appId, rsaPrivateKey, format, charset,
                alipayPublicKey, signType);
        AlipayTradeQueryRequest queryRequest = new AlipayTradeQueryRequest();
        AlipayTradePayModel model = new AlipayTradePayModel();
        // 惠民平台订单号
        model.setOutTradeNo(outTradeNo);
        // 封装请求参数
        queryRequest.setBizModel(model);
        PaymentResponseDTO dto;
        try {
            // 请求支付宝接口
            AlipayTradeQueryResponse qr = client.execute(queryRequest);
            // 接口调用成功
            if (AliCodeConstants.SUCCESSCODE.equals(qr.getCode())) {
                // 将支付宝响应的状态转换为惠民平台的状态
                TradeStatus tradeStatus = covertAliTradeStatusTohuiminCode(qr.getTradeStatus());
                dto = PaymentResponseDTO.success(qr.getTradeNo(), qr.getOutTradeNo(), tradeStatus,
                        qr.getMsg() + " " + qr.getSubMsg());
                log.info("‐‐‐‐查询支付宝H5支付结果" + JSON.toJSONString(dto));
                return dto;
            }
        } catch (AlipayApiException e) {
            log.warn(e.getMessage(), e);
        }
        dto = PaymentResponseDTO.fail("查询支付宝支付结果异常", outTradeNo, TradeStatus.UNKNOWN);
        return dto;
    }

    private TradeStatus covertAliTradeStatusTohuiminCode(String tradeStatus) {
        switch (tradeStatus) {
            case AliCodeConstants.WAIT_BUYER_PAY:
                return TradeStatus.USERPAYING;
            case AliCodeConstants.TRADE_SUCCESS:
            case AliCodeConstants.TRADE_FINISHED:
                return TradeStatus.SUCCESS;
            default:
                return TradeStatus.FAILED;
        }
    }

}
